﻿using System.Text;

namespace OpenCompiler.Scanning
{
	public unsafe static class TokenHelper
	{
		public static bool IsWhiteSpace(char character)
		{
			if (character == ' ' ||
				character == '\t')
			{
				return true;
			}
			return false;
		}

		public static int GetWhiteSpacePhysicalLength(char character)
		{
			return 1;
		}

		public static int GetWhiteSpaceVirtualLength(char character)
		{
			if( character == ' ')
			{
				return 1;
			} else if( character == '\t')
			{
				return Indentation.TabSize;
			}
			return 0;
		}

		public static bool IsEOL(char character)
		{
			if( character == '\n')
			{
				return true;
			}
			return false;
		}


		public static string GetToken(ref char* stringPointer, ref int remainingCharacters, char[] allowedCharacters)
		{
			var tokenBuilder = new StringBuilder();

			for (; ; )
			{
				if (remainingCharacters <= 0)
				{
					break;
				}
				var isOk = false;
				var currentChar = stringPointer[0];
				for (var allowedCharacterIndex = 0; allowedCharacterIndex < allowedCharacters.Length; allowedCharacterIndex++)
				{
					if (allowedCharacters[allowedCharacterIndex] == currentChar)
					{
						isOk = true;
						break;
					}
				}

				if (!isOk)
				{
					break;
				}
				tokenBuilder.Append(currentChar);
				remainingCharacters--;
				stringPointer++;
			}

			return tokenBuilder.ToString();
		}

		public static string GetTokenFromEnclosure(ref char* stringPointer, ref int remainingCharacters, char endEnclosure)
		{
			var tokenBuilder = new StringBuilder();
			var isFirst = true;


			for (; ; )
			{
				if (remainingCharacters <= 0)
				{
					break;
				}

				var currentChar = stringPointer[0];
				tokenBuilder.Append(currentChar);


				stringPointer++;
				remainingCharacters--;
				if (currentChar == endEnclosure && !isFirst)
				{
					break;
				}
				isFirst = false;
			}
			return tokenBuilder.ToString();
		}

		public static bool IsCharacter(char character, char[] allowedCharacters)
		{
			var isAllowed = false;
			for (var characterIndex = 0; characterIndex < allowedCharacters.Length; characterIndex++)
			{
				if (character == allowedCharacters[characterIndex])
				{
					isAllowed = true;
					break;
				}
			}
			return isAllowed;
		}

		public static bool IsMatch(char* stringPointer, int remainingCharacters, char* stringToMatch, int length)
		{
			var matchingCharacters = 0;
			var desiredLength = length;
			var index = 0;
			for( ;; )
			{
				if( remainingCharacters <= 0 || length <= 0)
				{
					break;
				}

				if(stringPointer[index] == stringToMatch[index])
				{
					matchingCharacters++;
				}

				index++;
				length--;
				remainingCharacters--;
			}

			return matchingCharacters == desiredLength;
		}

		public static int CountCharacterOccurence(char* stringPointer, int length, char letterToCount)
		{
			var count = 0;
			while( length > 0 )
			{
				if(stringPointer[0] == letterToCount )
				{
					count++;
				}

				stringPointer++;
				length--;
			}
			return count;
		}
	}
}
